home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / LISTBOX.PAK / LISTBOXX.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  17KB  |  603 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //----------------------------------------------------------------------------
  5. #include <owl/pch.h>
  6. #include <owl/applicat.h>
  7. #include <owl/framewin.h>
  8. #include <owl/static.h>
  9. #include <owl/listbox.h>
  10. #include <owl/inputdia.h>
  11. #include <owl/validate.h>
  12. #include <string.h>
  13. #include "listbox.rh"
  14.  
  15. //
  16. // List box ids.
  17. //
  18. const int ID_LB_BASE      = 200;
  19. const int ID_STANDARD     = ID_LB_BASE;
  20. const int ID_MULTI_SEL    = ID_LB_BASE + 1;
  21. const int ID_MULTI_COLUMN = ID_LB_BASE + 2;
  22.  
  23. //
  24. // class TListBoxWindow
  25. // ~~~~~ ~~~~~~~~~~~~~~
  26. class TListBoxWindow : public TWindow {
  27.   public:
  28.     TListBoxWindow(TWindow* parent = 0);
  29.  
  30.     // Message response functions
  31.     //
  32.  
  33.     void EvLBNSelChange();
  34.  
  35.     void CmStandard();               // create standard list box.
  36.     void CmMultiSel();               // create multi-select list box.
  37.     void CmMultiColumn();            // create multi-column list box.
  38.     void CmAddString();              // add string to list box.
  39.     void CmAddStringAt();            // add string at index position.
  40.     void CmFindString();             // goto index of given string, display string.
  41.     void CmFindStringAt();           // goto index, display string.
  42.     void CmDeleteString();           // delete string.
  43.     void CmDeleteStringAt();         // delete string at index.
  44.     void CmClear();                  // clear ListBox.
  45.     void CmDirList();                // show directory list.
  46.  
  47.     // Command enablers.
  48.     //
  49.     void CmEnableStandard(TCommandEnabler& commandHandler);
  50.     void CmEnableMultiSel(TCommandEnabler& commandHandler);
  51.     void CmEnableMultiColumn(TCommandEnabler& commandHandler);
  52.     void CmEnableOther(TCommandEnabler& commandHandler);
  53.  
  54.   private:
  55.     TListBox* ListBox;                 // list box.
  56.     TStatic*  CurSelOfListBox;         // text of selected string.
  57.     TStatic*  CurSelIndexOfListBox;    // index of selected string.
  58.     TStatic*  SelStringLength;         // length of selected string.
  59.     TStatic*  ItemCount;               // number of items in list box.
  60.     TStatic*  TopIndex;                // index of first visible item.
  61.     TStatic*  SelCount;                // # of selected items.
  62.     TStatic*  SelStrings;              // first 3 selected strings.
  63.     TStatic*  SelIndexes;              // first 3 indexes.
  64. #if defined(WIN32)
  65.     TStatic*  AnchorIndex;             // First item of multiselect.
  66. #endif
  67.  
  68.     int       WhichListBox;            // current ListBox.
  69.  
  70.     static const int TextLen;                 // length of input text.
  71.  
  72.     void  ResetTextFields();                   // reset text fields to blanks.
  73.     void  UpdateTextFields();                  // updates from list box.
  74.     int   InputString(char* pmpt, char* s);    // get string from user.
  75.     int   InputNumber(char* pmpt, char* s);    // get number from user.
  76.                                                // get string and number.
  77.     int   InputStringAndNumber(char* pmpt, char* s, int& n);
  78.  
  79.   DECLARE_RESPONSE_TABLE(TListBoxWindow);
  80. };
  81.  
  82. DEFINE_RESPONSE_TABLE1(TListBoxWindow, TWindow)
  83.   EV_LBN_SELCHANGE(ID_STANDARD,     EvLBNSelChange),
  84.   EV_LBN_SELCHANGE(ID_MULTI_SEL,    EvLBNSelChange),
  85.   EV_LBN_SELCHANGE(ID_MULTI_COLUMN, EvLBNSelChange),
  86.   EV_COMMAND(CM_STANDARD,           CmStandard),
  87.   EV_COMMAND(CM_MULTI_SEL,          CmMultiSel),
  88.   EV_COMMAND(CM_MULTI_COLUMN,       CmMultiColumn),
  89.   EV_COMMAND(CM_ADD_STRING,         CmAddString),
  90.   EV_COMMAND(CM_ADD_STRING_AT,      CmAddStringAt),
  91.   EV_COMMAND(CM_FIND_STRING,        CmFindString),
  92.   EV_COMMAND(CM_FIND_STRING_AT,     CmFindStringAt),
  93.   EV_COMMAND(CM_DELETE_STRING,      CmDeleteString),
  94.   EV_COMMAND(CM_DELETE_STRING_AT,   CmDeleteStringAt),
  95.   EV_COMMAND(CM_CLEAR,              CmClear),
  96.   EV_COMMAND(CM_DIR_LIST,           CmDirList),
  97.  
  98.   EV_COMMAND_ENABLE(CM_STANDARD,         CmEnableStandard),
  99.   EV_COMMAND_ENABLE(CM_MULTI_SEL,        CmEnableMultiSel),
  100.   EV_COMMAND_ENABLE(CM_MULTI_COLUMN,     CmEnableMultiColumn),
  101.   EV_COMMAND_ENABLE(CM_ADD_STRING,       CmEnableOther),
  102.   EV_COMMAND_ENABLE(CM_ADD_STRING_AT,    CmEnableOther),
  103.   EV_COMMAND_ENABLE(CM_FIND_STRING,      CmEnableOther),
  104.   EV_COMMAND_ENABLE(CM_FIND_STRING_AT,   CmEnableOther),
  105.   EV_COMMAND_ENABLE(CM_DELETE_STRING,    CmEnableOther),
  106.   EV_COMMAND_ENABLE(CM_DELETE_STRING_AT, CmEnableOther),
  107.   EV_COMMAND_ENABLE(CM_CLEAR,            CmEnableOther),
  108.   EV_COMMAND_ENABLE(CM_DIR_LIST,         CmEnableOther),
  109. END_RESPONSE_TABLE;
  110.  
  111. const int TListBoxWindow::TextLen = 21;
  112.  
  113. //
  114. // Constructor.  Setup menu and text areas.
  115. //
  116. TListBoxWindow::TListBoxWindow(TWindow* parent)
  117. :
  118.   TWindow(parent)
  119. {
  120.   ListBox = 0;
  121.   WhichListBox = 0;
  122.  
  123.   // setup static text areas.
  124.   //
  125.   new TStatic(this, -1, "Current selection:",  200, 30, 122, 18, 18);
  126.   CurSelOfListBox = new TStatic(this, -1, " ",  392, 30, 158, 18, 25);
  127.  
  128.   new TStatic(this, -1, "Index of current selection:",  200, 52, 176, 18, 18);
  129.   CurSelIndexOfListBox = new TStatic(this, -1, " ",  392, 52, 158, 18, 25);
  130.  
  131.   new TStatic(this, -1, "Length of current selection:",  200, 76, 184, 18, 18);
  132.   SelStringLength = new TStatic(this, -1, " ",  392, 76, 158, 18, 25);
  133.  
  134.   new TStatic(this, -1, "Number of items:",  200, 98, 184, 18, 18);
  135.   ItemCount = new TStatic(this, -1, " ",  392, 98, 158, 18, 25);
  136.  
  137.   new TStatic(this, -1, "First visible item:",  200, 120, 184, 18, 18);
  138.   TopIndex = new TStatic(this, -1, " ",  392, 120, 158, 18, 25);
  139.  
  140.   new TStatic(this, -1, "<Multi-Select only>",  200, 142, 184, 18, 25);
  141.  
  142.   new TStatic(this, -1, "Number of selected items:",  200, 164, 184, 18, 25);
  143.   SelCount = new TStatic(this, -1, " ",  392, 164, 158, 18, 25);
  144.  
  145.   new TStatic(this, -1, "First 3 selected strings:",  200, 186, 184, 18, 25);
  146.   SelStrings = new TStatic(this, -1, " ",  392, 186, 158, 18, 35);
  147.  
  148.   new TStatic(this, -1, "Indices of first 3 selected strings:",  200, 208,
  149.               200, 18, 25);
  150.   SelIndexes = new TStatic(this, -1, " ",  392, 208, 158, 18, 25);
  151.  
  152. #if defined(WIN32)
  153.   new TStatic( this, -1, "Index of first item:", 200, 230, 184, 18, 25 );
  154.   AnchorIndex = new TStatic(this, -1, " ", 392, 230, 158, 18, 10 );
  155. #endif
  156.   
  157. }
  158.  
  159. //
  160. // A selection has taken place, update text info.
  161. //
  162. void
  163. TListBoxWindow::EvLBNSelChange()
  164. {
  165.   UpdateTextFields();
  166. }
  167.  
  168. //
  169. // 'ListBox|Standard' menu item.  Create simple list box and fill it with some
  170. // strings.
  171. //
  172. void
  173. TListBoxWindow::CmStandard()
  174. {
  175.   if (ListBox) {
  176.     ListBox->Destroy();
  177.     delete ListBox;
  178.   }
  179.   ListBox = new TListBox(this, ID_STANDARD, 10, 30, 150, 150);
  180.   ListBox->Attr.Style;
  181.   ListBox->Create();
  182.   ListBox->SetFocus();
  183.   ListBox->AddString("dog");
  184.   ListBox->AddString("bird");
  185.   ListBox->AddString("mouse");
  186.   ListBox->AddString("car");
  187.  
  188.   WhichListBox = ID_STANDARD;
  189.  
  190.   ResetTextFields();
  191.   UpdateTextFields();
  192. }
  193.  
  194. //
  195. // 'ListBox|Multi-Select' menu item.  Create multi-select list box and fill it
  196. // with some strings.
  197. //
  198. void
  199. TListBoxWindow::CmMultiSel()
  200. {
  201.   if (ListBox) {
  202.     ListBox->Destroy();
  203.     delete ListBox;
  204.   }
  205.   ListBox = new TListBox(this, ID_MULTI_SEL, 10, 30, 150, 150);
  206.   ListBox->Attr.Style |= LBS_MULTIPLESEL;
  207.   ListBox->Create();
  208.   ListBox->SetFocus();
  209.   ListBox->AddString("string1");
  210.   ListBox->AddString("Hello!");
  211.   ListBox->AddString("Box");
  212.  
  213.   WhichListBox = ID_MULTI_SEL;
  214.  
  215.   ResetTextFields();
  216.   UpdateTextFields();
  217. }
  218.  
  219. //
  220. // 'ListBox|Multi-Column' menu item.  Create multi-column list box and fill
  221. // it with some strings.
  222. //
  223. void
  224. TListBoxWindow::CmMultiColumn()
  225. {
  226.   if (ListBox) {
  227.     ListBox->Destroy();
  228.     delete ListBox;
  229.   }
  230.   ListBox = new TListBox(this, ID_MULTI_COLUMN, 10, 30, 150, 150);
  231.   ListBox->Attr.Style |= LBS_MULTICOLUMN;
  232.   ListBox->Attr.Style &= ~LBS_SORT;
  233.   ListBox->Create();
  234.   ListBox->SetFocus();
  235.   ListBox->SetColumnWidth(110);   // about half of the list box window.
  236.   ListBox->AddString("Have");
  237.   ListBox->AddString("a");
  238.   ListBox->AddString("nice");
  239.   ListBox->AddString("Day");
  240.   ListBox->AddString("blue");
  241.   ListBox->AddString("green");
  242.   ListBox->AddString("yellow");
  243.   ListBox->AddString("gold");
  244.   ListBox->AddString("red");
  245.   ListBox->AddString("black");
  246.   ListBox->AddString("white");
  247.   ListBox->AddString("grey");
  248.  
  249.   WhichListBox = ID_MULTI_COLUMN;
  250.  
  251.   ResetTextFields();
  252.   UpdateTextFields();
  253. }
  254.  
  255. //
  256. // Add a string to the list box.
  257. //
  258. void
  259. TListBoxWindow::CmAddString()
  260. {
  261.   char buf[TextLen] = "";
  262.  
  263.   if (InputString("Enter string:", buf)) {
  264.     ListBox->AddString(buf);
  265.     UpdateTextFields();
  266.   }
  267. }
  268.  
  269. //
  270. // Insert a string at a given index of the listbox.
  271. //
  272. void
  273. TListBoxWindow::CmAddStringAt()
  274. {
  275.   char buf[TextLen] = "";
  276.   int  index;
  277.  
  278.   if (InputStringAndNumber("Enter string:", buf, index))
  279.     if (ListBox->InsertString(buf, index) != LB_ERR)
  280.       UpdateTextFields();
  281.     else
  282.       MessageBox("Index out of range", "Error", MB_OK);
  283. }
  284.  
  285. //
  286. // Find string.  Tell list box to select string at given index.
  287. // Update text fields.
  288. //
  289. void
  290. TListBoxWindow::CmFindString()
  291. {
  292.   char buf[TextLen] = "";
  293.   int  index;
  294.  
  295.   if (InputString( "Enter string:", buf)) {
  296.     if ((index = ListBox->FindString(buf, -1)) != LB_ERR) {
  297.       if (WhichListBox == ID_MULTI_SEL)
  298.         ListBox->SetSel(index, TRUE);
  299.       else
  300.         ListBox->HandleMessage(LB_SETCURSEL, index, 0);
  301.       UpdateTextFields();
  302.  
  303.     }
  304.     else
  305.       MessageBox("String not found", "Error", MB_OK);
  306.   }
  307. }
  308.  
  309. //
  310. // Find string.  Tell list box to select string at given index.
  311. // Update text fields.  Assumes index input is correct, else atoi()
  312. // will return 0 and will be used to select the first string.
  313. //
  314. void
  315. TListBoxWindow::CmFindStringAt()
  316. {
  317.   char buf[TextLen] = "";
  318.   int  index;
  319.  
  320.   if (InputNumber("Enter number:", buf)) {
  321.     index = atoi(buf);
  322.     if (ListBox->GetString(buf, index) != LB_ERR) {
  323.       if (WhichListBox == ID_MULTI_SEL)
  324.         ListBox->SetSel(index, TRUE);
  325.       else
  326.         ListBox->HandleMessage(LB_SETCURSEL, index, 0);
  327.       UpdateTextFields();
  328.     }
  329.     else
  330.       MessageBox("Index out of range", "Error", MB_OK);
  331.   }
  332. }
  333.  
  334. //
  335. // Delete string.  Delete string input by user.
  336. //
  337. void
  338. TListBoxWindow::CmDeleteString()
  339. {
  340.   char buf[TextLen] = "";
  341.  
  342.   if (InputString("Enter string:", buf)) {
  343.     int index;
  344.     if ((index = ListBox->FindString(buf, 0)) != LB_ERR) {
  345.       ListBox->DeleteString(index);
  346.       UpdateTextFields();
  347.     }
  348.     else
  349.       MessageBox("String not found", "Error", MB_OK);
  350.   }
  351. }
  352.  
  353. //
  354. // Delete string.  Delete string at given index.
  355. //
  356. void
  357. TListBoxWindow::CmDeleteStringAt()
  358. {
  359.   char buf[TextLen] = "";
  360.   int  index;
  361.  
  362.   if (InputNumber("Enter number:", buf)) {
  363.     index = atoi(buf);
  364.     if (ListBox->GetString(buf, index) != LB_ERR) {
  365.       ListBox->DeleteString(index);
  366.       UpdateTextFields();
  367.     }
  368.     else
  369.       MessageBox("Index out of range", "Error", MB_OK);
  370.   }
  371. }
  372.  
  373. //
  374. // Clear.  Clear list box of all strings.
  375. //
  376. void
  377. TListBoxWindow::CmClear()
  378. {
  379.   ListBox->ClearList();
  380.   ResetTextFields();
  381. }
  382.  
  383. //
  384. // Directory list.  Add strings representing the files in the current
  385. // directory.
  386. //
  387. void
  388. TListBoxWindow::CmDirList()
  389. {
  390.   ListBox->DirectoryList(0, "*.*");    // all normal files.
  391.   UpdateTextFields();
  392. }
  393.  
  394. //
  395. // Command Enablers.
  396. //
  397.  
  398. void
  399. TListBoxWindow::CmEnableStandard(TCommandEnabler& commandHandler)
  400. {
  401.   commandHandler.Enable(WhichListBox != ID_STANDARD ||
  402.                         !ListBox);
  403. }
  404.  
  405. void
  406. TListBoxWindow::CmEnableMultiSel(TCommandEnabler& commandHandler)
  407. {
  408.   commandHandler.Enable(WhichListBox != ID_MULTI_SEL ||
  409.                         !ListBox);
  410. }
  411.  
  412. void
  413. TListBoxWindow::CmEnableMultiColumn(TCommandEnabler& commandHandler)
  414. {
  415.   commandHandler.Enable(WhichListBox != ID_MULTI_COLUMN ||
  416.                         !ListBox);
  417. }
  418.  
  419. void
  420. TListBoxWindow::CmEnableOther(TCommandEnabler& commandHandler)
  421. {
  422.   commandHandler.Enable(ListBox != 0);
  423. }
  424.  
  425.  
  426. //
  427. // Updates text fields that reflex the list box's state.
  428. //
  429. void
  430. TListBoxWindow::UpdateTextFields()
  431. {
  432.   char buf[3*(TextLen+1)] = "";                  // temporary buffers.
  433.   char buf2[3*(TextLen+1)] = "";
  434.   int  index = ListBox->GetSelIndex();       // Current selection.
  435.   int  strLen;                               // length of string in list box.
  436.   int  multiSelCnt = ListBox->GetSelCount(); // # of selections.
  437.  
  438.   if (index != LB_ERR || multiSelCnt) {  // is something selected?
  439.     if (WhichListBox == ID_MULTI_SEL) {
  440.       char far* strs[3];
  441.       int  indexes[3];
  442.  
  443.       // display number of strings selected.
  444.       //
  445.       itoa(multiSelCnt, buf, 10);
  446.       SelCount->SetText(buf);
  447.  
  448.       // display first 3 selected strings.
  449.       //
  450.       strs[0] = new char[TextLen+1];
  451.       strs[0][0] = 0;
  452.       strs[1] = new char[TextLen+1];
  453.       strs[1][0] = 0;
  454.       strs[2] = new char[TextLen+1];
  455.       strs[2][0] = 0;
  456.       ListBox->GetSelStrings(strs, 3, TextLen);
  457.       strcpy(buf, strs[0]);
  458.       strcat(buf, "  ");
  459.       strcat(strcat(strcat(buf, strs[1]), "  "), strs[2]);
  460.       SelStrings->SetText(buf);
  461.  
  462.       // display indexes of first 3 selected strings.
  463.       //
  464.       int count = ListBox->GetSelIndexes(indexes, 3);
  465.       if (count != LB_ERR) {
  466.         for (int i = 0; i < count; i++) {
  467.           itoa(indexes[i], buf, 10);
  468.           strcat(strcat(buf2, buf), "  ");
  469.         }
  470.         SelIndexes->SetText( buf2 );
  471.       }
  472.  
  473. #if defined(WIN32)
  474.       // Display index of first selected item
  475.       //
  476.       int num = ListBox->GetAnchorIndex();
  477.       if( num != LB_ERR )  {
  478.         char buf[16];
  479.         wsprintf( buf, "%d", num );
  480.         AnchorIndex->SetText( buf );
  481.       }
  482. #endif
  483.       delete strs[0];
  484.       delete strs[1];
  485.       delete strs[2];
  486.     }
  487.     else {
  488.       // display selected string.
  489.       //
  490.       ListBox->GetString(buf, index);
  491.       strLen = ListBox->GetStringLen(index);
  492.       CurSelOfListBox->SetText(buf);
  493.  
  494.       // display length of selected string.
  495.       //
  496.       itoa(strLen, buf, 10);
  497.       SelStringLength->SetText(buf);
  498.  
  499.       // display index of currently selected string.
  500.       //
  501.       itoa(index, buf, 10);
  502.       CurSelIndexOfListBox->SetText(buf);
  503.     }
  504.     // display number of items in list box.
  505.     //
  506.     itoa(ListBox->GetCount(), buf, 10);
  507.     ItemCount->SetText(buf);
  508.  
  509.     // display index of first visible item in list box.
  510.  
  511.     itoa(ListBox->GetTopIndex(), buf, 10);
  512.     TopIndex->SetText(buf);
  513.   }
  514.   else
  515.     ResetTextFields();
  516. }
  517.  
  518. //
  519. // Reset text fields to blanks or default values.
  520. //
  521. void
  522. TListBoxWindow::ResetTextFields()
  523. {
  524.   CurSelOfListBox->SetText(" ");
  525.   SelStringLength->SetText(" ");
  526.   CurSelIndexOfListBox->SetText(" ");
  527.   ItemCount->SetText(" ");
  528.   TopIndex->SetText(" ");
  529.   SelCount->SetText(" ");
  530.   SelStrings->SetText(" ");
  531.   SelIndexes->SetText(" ");
  532. #if defined(WIN32)
  533.   AnchorIndex->SetText(" ");
  534. #endif
  535. }
  536.  
  537. //
  538. // Get string from user.  Return 1 if successful, 0 otherwise.
  539. // assumes string length of TextLen - 1.
  540. //
  541. int
  542. TListBoxWindow::InputString(char* pmpt, char* s)
  543. {
  544.   return TInputDialog(this, "String", pmpt, s, TextLen - 1).Execute() == IDOK;
  545. }
  546.  
  547. int
  548. TListBoxWindow::InputNumber( char* pmpt, char* s )
  549. {
  550.   return TInputDialog(this, "Number", pmpt, s, TextLen-1, 0,
  551.                       new TFilterValidator("0-9")).Execute() == IDOK;
  552. }
  553.  
  554. //
  555. // Get string and number (index) from user.  Return 1 if successful, 0
  556. // otherwise. Assumes string length of TextLen - 1.
  557. //
  558. int
  559. TListBoxWindow::InputStringAndNumber(char* pmpt, char* s, int& n)
  560. {
  561.   char sbuf[TextLen] = "";
  562.   char nbuf[TextLen] = "";
  563.   TInputDialog getStr(this, "String", pmpt, sbuf, TextLen - 1);
  564.  
  565.   // This input dialog has a validator that only accepts digits
  566.   //
  567.   TInputDialog getNum(this, "String", "Enter number:", nbuf, TextLen-1, 0,
  568.                       new TFilterValidator("0-9"));
  569.  
  570.   if (getStr.Execute() == IDOK &&
  571.       getNum.Execute() == IDOK) {
  572.     strcpy(s, sbuf);
  573.     n = atoi(nbuf);
  574.     return 1;
  575.   }
  576.   else
  577.     return 0;
  578. }
  579.  
  580. //----------------------------------------------------------------------------
  581.  
  582. //
  583. // class TListBoxApp
  584. // ~~~~~ ~~~~~~~~~~~
  585. class TListBoxApp : public TApplication {
  586.   public:
  587.     void InitMainWindow();
  588. };
  589.  
  590. void
  591. TListBoxApp::InitMainWindow()
  592. {
  593.   TFrameWindow* frame = new TFrameWindow(0, "ListBox Example", new TListBoxWindow);
  594.   frame->AssignMenu(IDM_LISTBOX_MENU);
  595.   SetMainWindow(frame);
  596. }
  597.  
  598. int
  599. OwlMain(int /*argc*/, char* /*argv*/ [])
  600. {
  601.   return TListBoxApp().Run();
  602. }
  603.